package view;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import controller.Controller;

/**
 * The GUI used for debugging the GCom system. Provides a list of currently held
 * messages and ways of manipulating the flow of messages in the GCom subsystem.
 * 
 */
public class GComDebugGUI extends JFrame {

    private static final long serialVersionUID = -2952274234041913728L;
    private final JPanel contentPane;
    private final Controller control;
    private final JButton btnRelease;
    private final JButton btnReleaseAll;
    private final JList debugHoldback;
    private final JList orderingHoldback;
    private final JList messageReceived;

    /**
     * Create the frame.
     * 
     */
    public GComDebugGUI(final Controller control) {
        this.control = control;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 1200, 360);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
        JPanel mainMidPanel = new JPanel();
        contentPane.add(mainMidPanel, BorderLayout.CENTER);
        mainMidPanel.setLayout(new BoxLayout(mainMidPanel, BoxLayout.X_AXIS));

        debugHoldback = new JList();
        orderingHoldback = new JList();
        messageReceived = new JList();

        JPanel debugPanel = new JPanel(new BorderLayout(0, 0));
        JPanel orderingPanel = new JPanel(new BorderLayout(0, 0));
        JPanel messageRecvPanel = new JPanel(new BorderLayout(0, 0));

        JScrollPane scrollPaneDebugList = new JScrollPane(debugHoldback);
        debugPanel.add(scrollPaneDebugList, BorderLayout.CENTER);

        JScrollPane scrollPaneOrderingList = new JScrollPane(orderingHoldback);
        orderingPanel.add(scrollPaneOrderingList, BorderLayout.CENTER);

        JScrollPane scrollPaneReceivedList = new JScrollPane(messageReceived);
        messageRecvPanel.add(scrollPaneReceivedList, BorderLayout.CENTER);

        JLabel debugLabel = new JLabel("Debug Holdback");
        JLabel orderingLabel = new JLabel("Ordering Holdback");
        JLabel messageRecvLabel = new JLabel("Received filter");

        debugPanel.add(debugLabel, BorderLayout.NORTH);
        orderingPanel.add(orderingLabel, BorderLayout.NORTH);
        messageRecvPanel.add(messageRecvLabel, BorderLayout.NORTH);

        mainMidPanel.add(debugPanel);
        mainMidPanel.add(orderingPanel);
        mainMidPanel.add(messageRecvPanel);

        /* buttons */
        final JPanel bottomPanel = new JPanel();
        final FlowLayout flowLayout = (FlowLayout) bottomPanel.getLayout();
        flowLayout.setAlignment(FlowLayout.LEFT);
        contentPane.add(bottomPanel, BorderLayout.SOUTH);

        btnRelease = new JButton("Release Message");
        bottomPanel.add(btnRelease);

        btnReleaseAll = new JButton("Release All");
        bottomPanel.add(btnReleaseAll);
        setTitle("GCom Debug Client");

        registerListeners();
    }

    private void registerListeners() {

        btnRelease.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                final Object item = debugHoldback.getSelectedValue();
                if (item != null) {
                    control.debugRelease(item);
                    debugHoldback.setListData((control.debugGetDebugHoldback()));
                }
            }
        });
        btnReleaseAll.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                control.debugReleaseAll();
                debugHoldback.setListData((control.debugGetDebugHoldback()));
            }
        });

    }

    public void setDebugHoldbackData(final Object[] itemlist) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (itemlist != null) {
                    debugHoldback.setListData(itemlist);
                }
            }
        });

    }

    public void setOrderingHoldbackData(final Object[] itemlist) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (itemlist != null) {
                    orderingHoldback.setListData(itemlist);
                }
            }
        });

    }

    public void setReceivedData(final Vector<String> itemlist) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (itemlist != null) {
                    messageReceived.setListData(itemlist);
                }
            }
        });

    }

    public void setDebuggerTitle(final String title) {
        final JFrame gui = this;
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                gui.setTitle(title);
            }
        });
    }

}
